package com.czk.springcloud.config;

import lombok.SneakyThrows;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Field;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Author:ChenZhangKun
 * @Date: 2021/7/19 9:57
 */
public class FeignClientsServiceNameAppendBeanPostProcessor implements BeanPostProcessor, ApplicationContextAware {
    private ApplicationContext applicationContext;
    AtomicInteger atomicInteger=new AtomicInteger();
    @SneakyThrows
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        // 第一次初始化
        if (atomicInteger.getAndIncrement()==0){
            String beanNameOfFeignClientFactoryBean = "org.springframework.cloud.openfeign.FeignClientFactoryBean";
            // 反射
            Class<?> beanNameClz = Class.forName(beanNameOfFeignClientFactoryBean);
            // 拿到容器中的对象
            Map<String, ?> beansOfType = applicationContext.getBeansOfType(beanNameClz);
            // 遍历
            beansOfType.forEach((feignBeanName, beanOfFeignClientFactoryBean)->{
                try {
                    setField(beanNameClz,"name",beanOfFeignClientFactoryBean);
                    setField(beanNameClz,"url",beanOfFeignClientFactoryBean);
                } catch (Exception e) {
                    e.printStackTrace();
                }

                System.out.println(feignBeanName + "-->" + beanOfFeignClientFactoryBean);
            });
        }
        return null;
    }

    private void setField(Class<?> beanNameClz, String name, Object beanOfFeignClientFactoryBean) throws IllegalAccessException {
        Field field = ReflectionUtils.findField(beanNameClz, name);
        if (Objects.nonNull(field)){
            ReflectionUtils.makeAccessible(field);
            // 拿到值
            Object o = field.get(beanOfFeignClientFactoryBean);
            if (Objects.nonNull(o)){
                o=o.toString().replaceAll("env","PAYMENT");
                ReflectionUtils.setField(field,beanOfFeignClientFactoryBean,o);
            }
        }
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext=applicationContext;
    }
}
